﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using UFSSServerClasses;
using System.Collections;

namespace UFSSWebService
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class UFSSservice : System.Web.Services.WebService
    {
        [WebMethod]
        public UFSSUser[] getTopUsers(UserCreds uc, int amount)
        {
            if (!AuthenticateUser(uc))
                return null;
            try
            {
                ArrayList userlist = new ArrayList();
                userlist = UserAccess.getTopUsers(amount);
                UFSSUser[] userarray = new UFSSUser[userlist.Count];
                int temp = 0;
                foreach (UFSSUser uuser in userlist)
                {
                    userarray[temp] = uuser;
                    temp++;
                }
                return userarray;
            }
            catch
            {
                return null;
            }
        }
        [WebMethod]
        public UFSSFile[] getTopFiles(UserCreds uc,int amount)
        {
            if (!AuthenticateUser(uc))
                return null;
            try
            {
                ArrayList filelist = new ArrayList();
                filelist = FileAccess.getTopFiles(amount);
                UFSSFile[] filearray = new UFSSFile[filelist.Count];
                int temp = 0;
                foreach (UFSSFile ufile in filelist)
                {
                    filearray[temp] = ufile;
                    temp++;
                }
                return filearray;
            }
            catch
            {
                return null;
            }

        }
        [WebMethod]
        public UFSSSubscription[] getTopSubs(UserCreds uc,int amount)
        {
            if (!AuthenticateUser(uc))
                return null;
            try
            {
                ArrayList sublist = new ArrayList();
                sublist = SubAccess.getTopSubs(amount);
                UFSSSubscription[] subarray = new UFSSSubscription[sublist.Count];
                int temp = 0;
                foreach (UFSSSubscription usub in sublist)
                {
                    subarray[temp] = usub;
                    temp++;
                }
                return subarray;
            }
            catch
            {
                return null;
            }

        }
        [WebMethod]
        public UFSSFile[] getFilesByDate(UserCreds uc, DateTime start, DateTime end)
        {
            if (!AuthenticateUser(uc))
                return null;
            try
            {
                ArrayList filelist = new ArrayList();
                filelist = FileAccess.getFilesByDate(start, end);
                UFSSFile[] filearray = new UFSSFile[filelist.Count];
                int temp = 0;
                foreach (UFSSFile ufile in filelist)
                {
                    filearray[temp] = ufile;
                    temp++;
                }
                return filearray;
            }
            catch
            {
                return null;
            }
            

        }
        [WebMethod]
        public string[] searchUsers(UserCreds uc, string query)
        {
            if (!AuthenticateUser(uc))
                return null;
            string[] users = UserAccess.searchUsers(query);
            return users;

        }

        [WebMethod]
        public UFSSSubscription[] searchSubs(UserCreds uc,string query)
        {
            if (!AuthenticateUser(uc))
                return null;
            ArrayList sublist = SubAccess.searchSubs(query);
            UFSSSubscription[] subs = new UFSSSubscription[sublist.Count];
            for (int i = 0; i < sublist.Count; i++)
                subs[i] = (UFSSSubscription)sublist[i];
            return subs;
        }
        [WebMethod]
        public UFSSFile[] searchFiles(UserCreds uc,string query)
        {
            if (!AuthenticateUser(uc))
                return null;
            ArrayList filelist = FileAccess.searchFiles(query);
            UFSSFile[] files = new UFSSFile[filelist.Count];
            for (int i = 0; i < filelist.Count; i++)
                files[i] = (UFSSFile)filelist[i];
            return files;

        }

        [WebMethod]
        public UFSSFile getFileInfo(UserCreds uc, int fileid)
        {
            if (!AuthenticateUser(uc))
                return null;
            return FileAccess.getFileInfo(fileid);
        }

        [WebMethod]
        public string getUserName(int userid)
        {
            return DBAccess.getUsername(userid);
        }

        [WebMethod]
        public bool CreateUser(string fname, string lname, string username, string pass, string email)
        {
            try
            {
                string ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                return UserAccess.addUser(username, pass, fname, lname, email, ip);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool DelUser(string username)
        {
            try
            {
                return UserAccess.deluser(username);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool UploadFile(UserCreds uc,byte[] filedata,string filename, string subname)
        {
            int userid = DBAccess.getUserID(uc.Username);
            if (!AuthenticateUser(uc))
                return false;
            
                if (SubAccess.getSubOwner(SubAccess.getSubID(subname)) == userid || SubAccess.getSubID(subname)==-1)
                {
                    if (FileAccess.uploadFile(userid, filedata, filename, SubAccess.getSubID(subname)) != null)
                        return true;
                    return false;
                }
            return false;
        }
        [WebMethod]
        public UFSSFile[] getFiles(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            try
            {
                ArrayList filelist = new ArrayList();
                filelist = FileAccess.getFiles(DBAccess.getUserID(uc.Username));
                UFSSFile[] filearray = new UFSSFile[filelist.Count];
                int temp = 0;
                foreach (UFSSFile ufile in filelist)
                {
                    filearray[temp] = ufile;
                    temp++;
                }
                return filearray;
            }
            catch
            {
                return null;
            }
        }

        [WebMethod]
        public UFSSFile[] getUserFiles(string user)
        {
            try
            {
                ArrayList filelist = new ArrayList();
                filelist = FileAccess.getFiles(DBAccess.getUserID(user));
                UFSSFile[] filearray = new UFSSFile[filelist.Count];
                int temp = 0;
                foreach (UFSSFile ufile in filelist)
                {
                    filearray[temp] = ufile;
                    temp++;
                }
                return filearray;
            }
            catch
            {
            }
            return null;
        }
        
        [WebMethod]
        public int getSystemLimit(string property)
        {
            try
            {
                return Int32.Parse(SystemAccess.getSystemStat(property, true));
            }
            catch
            {
                return -1;
            }
        }
        [WebMethod]
        public bool LoginUser(ref UserCreds uc) //sets Token property in the passed UserCreds
        {
            try
            {
                if (UserAccess.login(uc.Username, uc.Password)!=null)
                {
                    uc.Token = (TokenHandler.AddToken(DBAccess.getUserID(uc.Username)).ToString());
                    return true;
                }
            }
            catch
            {
                return false;
            }
            return false;
        }
        
        [WebMethod]
        public bool DownloadFile(UserCreds uc, int fileid, ref byte[] buffer)
        {
            try
            {
                
                buffer = FileAccess.downloadFile(fileid, DBAccess.getUserID(uc.Username));
                return true;
            }
            catch
            {
                return false;
            }
        }
        
        [WebMethod]
        public bool LogoutUser(ref UserCreds uc)
        {
            try
            {
                if (AuthenticateUser(uc))
                {
                    TokenHandler.RemoveToken(uc.Token);
                    uc.Token = null;
                    return true;
                }
            }
            catch
            {
                return false;
            }
            return false;
        }
        
        [WebMethod]
        public bool ValidateToken(UserCreds uc)
        {
            return AuthenticateUser(uc);
        }
        
        public bool AuthenticateUser(UserCreds uc)
        {
            if (TokenHandler.checkToken(DBAccess.getUserID(uc.Username), uc.Token))
                return true;
            return false;
        }

        [WebMethod]
        public bool delFile(UserCreds uc, string filename)
        {
            if (!AuthenticateUser(uc))
                return false;
            
            if(FileAccess.deleteFile(FileAccess.getFileID(filename, DBAccess.getUserID(uc.Username)), DBAccess.getUserID(uc.Username)))
                return true;

            return false;
        }

        [WebMethod]
        public UFSSSubscription[] getSubs(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            try
            {
                ArrayList sublist = new ArrayList();
                sublist = SubAccess.getSubscription(DBAccess.getUserID(uc.Username));
                UFSSSubscription[] subarray = new UFSSSubscription[sublist.Count];
                int temp = 0;
                foreach (UFSSSubscription us in sublist)
                {
                    subarray[temp] = us;
                    temp++;
                }
                return subarray;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public UFSSSubscription[] getSubbedTo(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            try
            {
                ArrayList sublist = new ArrayList();
                sublist = SubAccess.getSubbedTo(DBAccess.getUserID(uc.Username));
                UFSSSubscription[] subarray = new UFSSSubscription[sublist.Count];
                int temp = 0;
                foreach (UFSSSubscription us in sublist)
                {
                    subarray[temp] = us;
                    temp++;
                }
                return subarray;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public UFSSSubscription[] getUserSubs(string user)
        {
            try
            {
                ArrayList sublist = new ArrayList();
                sublist = SubAccess.getSubscription(DBAccess.getUserID(user));
                UFSSSubscription[] subarray = new UFSSSubscription[sublist.Count];
                int temp = 0;
                foreach (UFSSSubscription us in sublist)
                {
                    subarray[temp] = us;
                    temp++;
                }
                return subarray;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public UFSSMessage[] getMessages(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            try
            {
                ArrayList message = new ArrayList();
                message = FriendAccess.getMessage(DBAccess.getUserID(uc.Username));
                UFSSMessage[] messarray = new UFSSMessage[message.Count];
                int temp = 0;
                foreach (UFSSMessage us in message)
                {
                    messarray[temp] = us;
                    temp++;
                }
                return messarray;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public string[] getFriends(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            string[] result;
            List<string> fl = new List<string>();
            try
            {
                fl = FriendAccess.getFriends(DBAccess.getUserID(uc.Username));
                result = new string[fl.Count()];
                for (int i = 0; i < fl.Count(); i++)
                {
                    result[i] = fl[i];
                }

                return result;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public string[] getUserFriends(string user)
        {
            string[] result;
            List<string> fl = new List<string>();
            try
            {
                fl = FriendAccess.getFriends(DBAccess.getUserID(user));
                result = new string[fl.Count()];
                for (int i = 0; i < fl.Count(); i++)
                {
                    result[i] = fl[i];
                }

                return result;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public bool createSub(UserCreds uc, string type, string name)
        {
            if (!AuthenticateUser(uc))
                return false;

            try
            {
                return SubAccess.addSub(type.ToUpper(), uc.Username, name);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool deleteSub(UserCreds uc, string name)
        {
            if (!AuthenticateUser(uc))
                return false;

            try
            {
                return SubAccess.delSub(uc.Username, name);
            }
            catch
            {
            }
            return false;
        }

        [WebMethod]
        public bool joinSubscriptin(UserCreds uc, string name)
        {
            if (!AuthenticateUser(uc))
                return false;
            try
            {
                return SubAccess.joinSub(uc.Username, name);
            }
            catch
            {
            }
             return false;
        }

        [WebMethod]
        public bool leaveSubscription(UserCreds uc, string name)
        {
            if (!AuthenticateUser(uc))
                return false;
            try
            {
                return SubAccess.leaveSub(uc.Username, name);
            }
            catch
            {
            }
            return false;
        }

        [WebMethod]
        public bool delFriend(UserCreds uc, string name)
        {
            if (!AuthenticateUser(uc))
                return false;

            try
            {
                return FriendAccess.rejectFriend(uc.Username, name);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool delMultiFriend(UserCreds uc, string[] name)
        {
            bool friend;
            if (!AuthenticateUser(uc))
                return false;

            try
            {
                for (int i = 0; i < name.Length; i++)
                {
                    friend = FriendAccess.rejectFriend(uc.Username, name[i].ToString());
                    
                    if (friend == false)
                        return false;
                }
            }
            catch
            {
            }

            return false;
        }
        [WebMethod]
        public bool addFriend(UserCreds uc, string name)
        {
            if(!AuthenticateUser(uc))
                return false;
            try
            {
                
                return FriendAccess.requestFriend(uc.Username, name);
            }
            catch
            {
                return false;
            }
        }


        [WebMethod]
        public string[] getRequestedFriends(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            string[] result;
            List<string> rl = new List<string>();
            try
            {
                rl = FriendAccess.getRequestedFriends(DBAccess.getUserID(uc.Username));
                result = new string[rl.Count()];
                for (int i = 0; i < rl.Count(); i++)
                {
                    result[i] = rl[i];
                }

                return result;
            }
            catch
            {
            }
            return null;
        }


        [WebMethod]
        public bool delMessage(UserCreds uc, int messID)
        {
            if (!AuthenticateUser(uc))
                return false;
            try
            {
                return FriendAccess.delMessage(messID);
            }
            catch
            {
            }
            return false;
        }

        [WebMethod]
        public bool sendMessage(UserCreds uc, string friendname, string message, string subject)
        {
            if (!AuthenticateUser(uc))
                return false;
            try
            {
                return FriendAccess.sendMessage(uc.Username, friendname, message, subject);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool acceptFriend(UserCreds uc, string friend)
        {
            if (!AuthenticateUser(uc))
                return false;
            try
            {
                return FriendAccess.addFriend(uc.Username, friend);
            }
            catch
            {
            }

            return false;
        }
        [WebMethod]
        public int getUserStat(UserCreds uc, string property)
        {
            if (!AuthenticateUser(uc))
                return -1;
            try
            {
                return Int32.Parse(UserAccess.getUserStat(DBAccess.getUserID(uc.Username), property));
            }
            catch
            {
                return -1;
            }
        }

        [WebMethod]
        public int getOtherUserStat(string user, string property)
        {
            try
            {
                return Int32.Parse(UserAccess.getUserStat(DBAccess.getUserID(user), property));
            }
            catch
            {
                return -1;
            }
        }

        [WebMethod]
        public bool rejectFriend(UserCreds uc, string friend)
        {
            if (!AuthenticateUser(uc))
                return false;
            try
            {
                return FriendAccess.rejectFriend(uc.Username, friend);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public string[] getUserInfo(UserCreds uc)
        {
            if (!AuthenticateUser(uc))
                return null;

            try
            {
                string[] info = new string[6];
                info = UserAccess.getUserInfo(uc.Username);
                return info;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public string[] getOtherUserInfo(string user)
        {
            try
            {
                string[] info = new string[6];
                info = UserAccess.getUserInfo(user);
                return info;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public UFSSSubscription getSubInfoByID(UserCreds uc, int id)
        {
            if (!AuthenticateUser(uc))
                return null;
            try
            {
                return SubAccess.getSubscriptionInfo(id);
            }
            catch
            { }
            return null;
        }
        
        [WebMethod]
        public UFSSSubscription getSubInfo(string sub)
        {
            try
            {
                return SubAccess.getSubscriptionInfo(SubAccess.getSubID(sub));
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public string[] getSubMembers(string subname)
        {
            ArrayList ar = new ArrayList();
            try
            {
                ar = SubAccess.getSubMembers(SubAccess.getSubID(subname));
                string[] member = new string[ar.Count];
                for (int i = 0; i < ar.Count; i++)
                {
                    member[i] = ar[i].ToString();
                }
                return member;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public UFSSFile[] getSubFiles(string subname)
        {
            try
            {
                ArrayList filelist = new ArrayList();
                filelist = SubAccess.getSubFiles(SubAccess.getSubID(subname));
                UFSSFile[] filearray = new UFSSFile[filelist.Count];
                int temp = 0;
                foreach (UFSSFile ufile in filelist)
                {
                    filearray[temp] = ufile;
                    temp++;
                }
                return filearray;
            }
            catch
            {
            }
            return null;
        }

        [WebMethod]
        public bool isFriend(UserCreds uc, string friend)
        {
            try
            {
                if (uc.Username.Equals(friend))
                    return true;

                if (FriendAccess.getRelationID(uc.Username, friend) != -1)
                    return true;
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool isSubbed(UserCreds uc, string sub)
        {
            try
            {
                return SubAccess.isSubbed(uc.Username, SubAccess.getSubID(sub));
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public bool updateUser(UserCreds uc, string fname, string lname, string email)
        {
            try
            {
                if (!AuthenticateUser(uc))
                return false;

                return UserAccess.updateUser(uc.Username, fname, lname, email);
            }
            catch
            {
            }
            return false;
        }

        [WebMethod]
        public bool updatePass(UserCreds uc, string prepass, string pass)
        {
            try
            {
                if (!AuthenticateUser(uc))
                    return false;

                if(!prepass.Equals(uc.Password))
                    return false;

                return UserAccess.updatePass(DBAccess.getUserID(uc.Username), pass);
            }
            catch
            {
            }

            return false;
        }

        [WebMethod]
        public string forgotPass(string username, string email)
        {
            try
            {
                return UserAccess.forgotPass(username, email);
            }
            catch
            {
            }

            return null;
        }
    }
}